/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include <FBase.h>
#include <memory>
#include "../Thread.h"

using namespace Osp::Base;

namespace liba
{
namespace threads
{

class Thread::Impl
	: public Runtime::IRunnable
{
public:
	Impl()
	{ }

	virtual Osp::Base::Object* Run(void)
	{
		if (owner_)
			owner_->run();

		return NULL;
	}

	void SetOwner(Thread* owner)
	{
		owner_ = owner;
	}

	bool Initialize()
	{
		thread_.reset(new Runtime::Thread());
		result r = thread_->Construct(*this);
		if (E_SUCCESS != r)
			AppLogException("Failed to initialize thread at %s:%d", __FILE__, __LINE__);
		return E_SUCCESS == r;
	}

	std::auto_ptr<Runtime::Thread> thread_;
	Thread* owner_;
};

Thread::Thread()
:	processID( 0 ),
	need_termination_flag( false ),
	impl( new Impl() )
{
	impl->SetOwner(this);
}

Thread::~Thread()
{
	if (impl)
	{
		delete impl;
		impl = 0;
	}
}

bool Thread::start()
{
	if (impl->thread_.get())
		return false;

	bool ok = impl->Initialize();
	if (ok)
	{
		result startResult = impl->thread_->Start();
		if (E_SUCCESS != startResult)
			AppLogException("Failed to start thread at %s:%d", __FILE__, __LINE__);
		return E_SUCCESS == startResult;
	}

	return ok;
}

void Thread::wait_termination()
{
	if(impl->thread_.get())
	{
		if (E_SUCCESS != impl->thread_->Join())
			AppLogException("Failed to join thread at %s:%d", __FILE__, __LINE__);
		impl->thread_.reset();
	}
}

void Thread::request_termination()
{
	need_termination_flag = true;
}

bool Thread::need_termination()volatile const
{
	return need_termination_flag;
}

bool Thread::set_priority( int priority )
{
	return false;
}

void Thread::resume()
{
}

void Thread::suspend()
{
}

} // namespace threads
} //namespace liba
